const fs = require('fs');
const path = require('path');
var mkdirs = require('mkdirs');
const images = require("images");
const sendToWormhole = require('stream-wormhole');
const Controller = require('egg').Controller;
var zipper = require('zip-local');
function saveStream(stream, filepath, dir) {
  return new Promise((resolve, reject) => {
    if (filepath.indexOf('/read-error-') > 0) {
      stream.once('readable', () => {
        const buf = stream.read(10240);
        console.log('read %d bytes', buf.length);
        setTimeout(() => {
          reject(new Error('mock read error'));
        }, 1000);
      });
    } else {

      if (!fs.existsSync(dir)) {
        mkdirs(dir)
      }

      const ws = fs.createWriteStream(filepath);
      stream.pipe(ws);
      ws.on('error', reject);
      ws.on('finish', resolve);
    }
  });


}


class uploaderController extends Controller {
  /**
   * 原图上传
   * @returns {Promise<void>}
   */
  async upload() {
    const ctx = this.ctx;
    const stream = await ctx.getFileStream();
    let file_dir = this.app.config.tempSwitch == 'on' ? this.app.config.tempname+'/'+ new Date().Format("yyyyMMdd") : new Date().Format("yyyyMMdd");
    let file_name = new Date().getTime() + stream.filename.substring(stream.filename.lastIndexOf("."), stream.filename.length);
    let filepath = path.join(this.app.config.uploadDir, `${file_dir}/${file_name}`);

    this.logger.warn('Saving %s to %s', file_name, filepath);
    // 文件处理，上传到云存储等等
    let resp = {};
    try {
      await saveStream(stream, filepath, path.join(this.app.config.uploadDir, `${file_dir}`));
      resp.code = 0;
      resp.url = `/public/upload/${file_dir}/${file_name}`;
    } catch (err) {
      // 必须将上传的文件流消费掉，要不然浏览器响应会卡死
      resp.code = 1;
      await sendToWormhole(stream);

      throw err;
    }

    ctx.body = resp
  }

  /**
   * 压缩720上传
   * @returns {Promise<void>}
   */
  async zipimg() {
    const { ctx, service,app } = this;
    const stream = await ctx.getFileStream();

    let archive = ctx.query.archive;

    if(!app.lodash.isEmpty(archive)){
        if(archive = 'archive'){
            archive = true;
        }else{
          archive = false;
        }
    }else{
      archive = false;
    }

    console.log("saving zip-img : 720");
    let file_dir = this.app.config.tempSwitch == 'on' ? this.app.config.tempname +"/"+ new Date().Format("yyyyMMdd") : new Date().Format("yyyyMMdd");
    file_dir = archive ? this.app.config.archive + "/" + file_dir : file_dir;
    let file_name = new Date().getTime() + stream.filename.substring(stream.filename.lastIndexOf("."), stream.filename.length);
    let filepath = path.join(this.app.config.uploadDir, `${file_dir}/eggimg0/${file_name}`);
    let file720path = path.join(this.app.config.uploadDir, `${file_dir}/eggimg720/${file_name}`);

    this.logger.warn('Saving 0: %s to %s', file_name, filepath);
    this.logger.warn('Saving 720: %s to %s', file_name, file720path);
    try {
      await saveStream(stream, filepath, path.join(this.app.config.uploadDir, `${file_dir}/eggimg0`));
      if (!fs.existsSync(path.join(this.app.config.uploadDir, `${file_dir}/eggimg720`))) {
        mkdirs(path.join(this.app.config.uploadDir, `${file_dir}/eggimg720`))
      }

      images(filepath) //Load image from file
        //加载图像文件
        .size(720) //Geometric scaling the image to 400 pixels width
        //等比缩放图像到400像素宽
        //.draw(images("logo.png")) //Drawn logo at coordinates (10,10) , 10, 10
        //在(10,10)处绘制Logo
        .save(file720path, { //Save the image to a file,whih quality 50
          quality: 100 //保存图片到文件,图片质量为50
        });

    } catch (err) {
      await sendToWormhole(stream);
      throw err;
    }

    // console.info(service.utils.imgUtil(`/public/upload/${file_dir}/eggimg720/${file_name}`))

    this.ctx.body =
      {
        code: '0',
        msg: "error message",
        url: `/public/upload/${file_dir}/eggimg720/${file_name}`
      }
  }

    /**
     * 上传录音
     */
  async voice(){
    const { ctx, service,app } = this;
    const stream = await ctx.getFileStream();

    let archive = ctx.query.archive;

    if(!app.lodash.isEmpty(archive)){
        if(archive = 'archive'){
            archive = true;
        }else{
            archive = false;
        }
    }else{
        archive = false;
    }

    console.log("saving voice");
    let file_dir = this.app.config.tempSwitch == 'on' ? this.app.config.tempname +"/"+ new Date().Format("yyyyMMdd") : new Date().Format("yyyyMMdd");
    file_dir = archive ? this.app.config.archive + "/" + file_dir : file_dir;
    let file_name = new Date().getTime() + stream.filename.substring(stream.filename.lastIndexOf("."), stream.filename.length);
    let filepath = path.join(this.app.config.uploadDir, `${file_dir}/voice/${file_name}`);

    this.logger.warn('Saving voice: %s to %s', file_name, filepath);
    try {
        await saveStream(stream, filepath, path.join(this.app.config.uploadDir, `${file_dir}/voice`));
    } catch (err) {
        await sendToWormhole(stream);
        throw err;
    }

    // console.info(service.utils.voiceUtil(`/public/upload/${file_dir}/voice/${file_name}`));

    this.ctx.body =
    {
        code: '0',
        msg: "error message",
        url: `/public/upload/${file_dir}/voice/${file_name}`
    }
  }

  /**
   * 下载二维码
   */
  async notBindQrcodes() {

    const { ctx, service, app } = this;
    const Op = app.Sequelize.Op;

    let time = new Date().getTime().toString();
    let type = this.ctx.query.type;
    let code = this.ctx.query.code;
    let sql_table = 'fd_qrcode';

    let sql0 = `SELECT * FROM ${sql_table} WHERE deleted = '0' AND qrcode_type = '${type}' AND number = '${code}'`;
    let filelist = await ctx.model.query(sql0, { raw: true, type: app.Sequelize.QueryTypes.SELECT });
    if (!fs.existsSync(path.join(this.app.config.uploadDir, "zip/"))) {
      mkdirs(path.join(this.app.config.uploadDir, "zip/"))
    }
    if (!fs.existsSync(path.join(this.app.config.uploadDir, "pack/"))) {
      mkdirs(path.join(this.app.config.uploadDir, "pack/"))
    }
    for (var i = 0; i < filelist.length; i++) {
      var file = filelist[i];
      if (file != null && file != '') {
        if (file.path != '' && file.path != null && file.path != 'null' && file.path != undefined) {
          //复制文件到压缩的路径下
          //读取源文件
          let file_name = file.code;//卡牌编号作为文件名
          if (fs.existsSync(path.join(this.app.config.fileDir + file.path))) {
            var readStream = fs.readFileSync(path.join(this.app.config.fileDir + file.path));
            //在目标路径生成副本，并以数据库中的名字命名，不然名字是一串数字,同名会直接覆盖
            fs.writeFileSync(this.app.config.uploadDir + "zip/" + file_name + ".png", readStream);
          }
        }
      }
    }
    //同步方法：生成zip包，将uploadDir/zip下的文件打包到uploadDir/pack,名字是时间戳，需要定时任务删除这些文件
    zipper.sync.zip(this.app.config.uploadDir + "zip/").compress().save(this.app.config.uploadDir + "pack/" + time + ".zip");
    //清空uploadDir/zip下的文件
    let dir = this.app.config.uploadDir + "zip";
    var files = fs.readdirSync(dir);//读取文件夹
    files.forEach(function (file) {
      var stats = fs.statSync(dir + '/' + file);
      if (stats.isDirectory()) {
        emptyDir(dir + '/' + file);
      } else {
        fs.unlinkSync(dir + '/' + file);
        //console.log("删除文件"+dir+'/'+file+"成功");
      }
    });
    //zip包生成流供下载
    this.ctx.attachment("二维码打包下载.zip");
    this.ctx.set('Content-Type', 'application/octet-stream');
    this.ctx.body = fs.readFileSync(this.app.config.uploadDir + "pack/" + time + ".zip");

  }

}

module.exports = uploaderController;